package com.yn.service.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yn.common.constants.Constants;
import com.yn.common.enums.NextFlagEnum;
import com.yn.common.exception.TransitException;
import com.yn.common.model.zy.DoctorDepartmentLink;
import com.yn.common.model.zy.OrganDepartment;
import com.yn.common.page.BasePage;
import com.yn.common.request.sc.PageParamRequest;
import com.yn.common.request.zy.OrganDepartmentQueryRequest;
import com.yn.common.request.zy.OrganDepartmentRequest;
import com.yn.common.response.zy.OrganDepartmentTreeResponse;
import com.yn.common.utils.DateUtil;
import com.yn.service.dao.zy.OrganDepartmentMapper;
import com.yn.service.service.IDoctorDepartmentLinkService;
import com.yn.service.service.IOrganDepartmentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;


/**
 * <p>
 * 医院科室 服务实现类
 * </p>
 *
 * @author xuquanjun
 * @since 2025-07-10
 */
@Service
public class OrganDepartmentServiceImpl extends ServiceImpl<OrganDepartmentMapper, OrganDepartment> implements IOrganDepartmentService {

    @Autowired
    private IDoctorDepartmentLinkService doctorDepartmentLinkService;

    /**
     * 添加医院科室信息
     * @param request 医院科室新增对象
     * @return
     */
    @Override
    @Transactional
    public void saveDepartmentInfo(OrganDepartmentRequest request) {
        //根据科室名称和父类等级查询科室信息
        OrganDepartment one = lambdaQuery().eq(OrganDepartment::getDepartmentName, request.getDepartmentName())
                .eq(OrganDepartment::getParentId, request.getParentId())
                .eq(OrganDepartment::getIsDelTag, 0)
                .one();
        if (one != null) {
            throw new TransitException("已有该科室");
        }
        OrganDepartment transform = OrganDepartmentRequest.transform(request);
        if (transform == null){
            throw new TransitException("参数错误");
        }
        //设置下级为 无
        transform.setIsNexFalg(NextFlagEnum.NO.getCode());
        //判断是否有父级id
        if(transform.getParentId() == 0){
            transform.setLevel(1);
        }else{
            //获取父级科室信息
            OrganDepartment parentDepartment = getById(transform.getParentId());
            if(parentDepartment == null){
                throw new TransitException("父级科室不存在");
            }
            //设置等级为父级科室等级+1
            transform.setLevel(parentDepartment.getLevel() + 1);
            //判断父级科室是否有下级，如果没有则设置有下级，更新父类科室信息
            if(Objects.equals(parentDepartment.getIsNexFalg(), NextFlagEnum.NO.getCode())){
                parentDepartment.setIsNexFalg(NextFlagEnum.YES.getCode());
                updateById(parentDepartment);
            }
        }
        save(transform);
    }

    /**
     * 删除医院科室信息
     * @param id 科室id
     * @return
     */
    @Override
    public void deleteDepartmentInfo(Integer id) {
        OrganDepartment department = getById(id);
        // 判断当前科室下是否有下级科室
        if(Objects.equals(department.getIsNexFalg(), NextFlagEnum.YES.getCode())){
            throw new TransitException("当前科室下有下级科室，请先删除下级科室");
        }
        //判断当前科室是否关联医生信息
        Integer count = doctorDepartmentLinkService.lambdaQuery()
                .eq(DoctorDepartmentLink::getBelongingDepartmentId, id)
                .count();
        if(count > 0){
            throw new TransitException("当前科室下关联了医生信息，请先删除医生信息");
        }
        //检查该科室的父节点是否存在，若存在且该科室是其唯一子节点，则更新父节点为“无下级”。
        Integer parentId = department.getParentId();
        if(parentId != 0){
            //查询同父级节点数量，如果大于1，则不改变父节点信息
            Integer parentNums = lambdaQuery().eq(OrganDepartment::getParentId, parentId).count();
            if(parentNums == 1){
                //同父级节点个数为1，代表只有该个子节点，更新父级信息
                OrganDepartment parentDepartment = getById(parentId);
                if(parentDepartment== null){
                    throw new TransitException("删除错误");
                }
                //父级节点为没有字节点
                parentDepartment.setIsNexFalg(NextFlagEnum.NO.getCode());
                updateById(parentDepartment);
            }
        }
        removeById(id);
    }

    /**
     * 修改医院科室信息
     * @param request 医院科室修改对象
     * @return
     */
    @Override
    @Transactional
    public void updateDepartmentInfo(OrganDepartmentRequest request) {
        if(request.getId() == null){
            throw new TransitException("更新的科室信息不能为空");
        }

        OrganDepartment department = getById(request.getId());

        //检查该科室的父节点是否存在，若存在且该科室是其唯一子节点，则更新父节点为“无下级”。
        Integer parentId = department.getParentId();
        if(parentId != 0){
            //查询同父级节点数量，如果大于1，则不改变父节点信息
            Integer parentNums = lambdaQuery().eq(OrganDepartment::getParentId, parentId).count();
            if(parentNums == 1){
                //同父级节点个数为1，代表只有该个子节点，更新父级信息
                OrganDepartment parentDepartment = getById(parentId);
                if(parentDepartment== null){
                    throw new TransitException("更新错误");
                }
                //父级节点为没有字节点
                parentDepartment.setIsNexFalg(NextFlagEnum.NO.getCode());
                updateById(parentDepartment);
            }
        }
        BeanUtil. copyProperties(request, department);
        //根据父节点设置科室层级：若父节点为根节点（parentId=0），则层级为1；否则根据父节点层级+1设置
        if(request.getParentId()==0){
            department.setLevel(1);
        }else{
            //根据parentId查询新父级节点
            OrganDepartment parentDepartment = getById(request.getParentId());
            if(parentDepartment==null){
                throw new TransitException("父节点信息有误");
            }
            if(Objects.equals(parentDepartment.getIsNexFalg(), NextFlagEnum.NO.getCode())){
                //将新父节点更新为有下级
                parentDepartment.setIsNexFalg(NextFlagEnum.YES.getCode());
                updateById(parentDepartment);
            }
            department.setLevel(parentDepartment.getLevel()+1);
        }
        updateById(department);
    }

    /**
     * 获取科室树状图
     * @return List<OrganDepartmentTreeResponse> 科室树状图
     */
    @Override
    public List<OrganDepartmentTreeResponse> getListTree() {
        //找到parentId为0的所有节点
        List<OrganDepartment> list = lambdaQuery().eq(OrganDepartment::getParentId, 0).eq(OrganDepartment::getIsDelTag, false).list();
        if (CollUtil.isEmpty(list)) {
            return new ArrayList<>();
        }
        List<OrganDepartmentTreeResponse> responses = list.stream().map(OrganDepartmentTreeResponse::transform).collect(Collectors.toList());
        findTree(responses, list.stream().map(OrganDepartment::getId).collect(Collectors.toList()));

        return responses;
    }

    /**
     * 获取科室信息分页列表
     *
     * @param request     查询条件
     * @param pageRequest 分页条件
     * @return BaseResult<BasePage < OrganDepartmentDTO>>
     */
    @Override
    public PageInfo<OrganDepartmentTreeResponse> getPageList(OrganDepartmentQueryRequest request, PageParamRequest pageRequest) {

        Page<OrganDepartment> departmentPage = PageHelper.startPage(pageRequest.getPage(), pageRequest.getLimit());

        LambdaQueryWrapper<OrganDepartment> lambdaQuery = new LambdaQueryWrapper<>();
        //构建查询条件
        //科室名称模糊查询
            lambdaQuery.like(StrUtil.isNotEmpty(request.getDepartmentName()),OrganDepartment::getDepartmentName, request.getDepartmentName());
        //等级查询
            lambdaQuery.eq(Objects.nonNull(request.getLevel()),OrganDepartment::getLevel, request.getLevel());
        //时间区间查询
        if(StrUtil.isNotEmpty(request.getBeginTime()) && StrUtil.isNotEmpty(request.getEndTime())){
            Date beginTime = DateUtil.strToDate(request.getBeginTime(), Constants.DATE_FORMAT);
            Date endTime = DateUtil.strToDate(request.getEndTime(), Constants.DATE_FORMAT);
            lambdaQuery.between(OrganDepartment::getCreateTime, beginTime, endTime);
        }
        //父级id
        if(!Objects.isNull(request.getParentId()) && request.getParentId()>0){
            lambdaQuery.eq(OrganDepartment::getParentId, request.getParentId());
        }


        List<OrganDepartment> departmentList = baseMapper.selectList(lambdaQuery);
        List<OrganDepartmentTreeResponse> treeResponses =new ArrayList<>(departmentList.size());
        if (CollUtil.isEmpty(departmentList)){
            return BasePage.copyPageInfo(departmentPage, treeResponses);
        }




        for (OrganDepartment department : departmentList) {
            treeResponses.add(OrganDepartmentTreeResponse.transform(department));
        }
        if(CollUtil.isNotEmpty(treeResponses)){
            return BasePage.copyPageInfo(departmentPage, treeResponses);
        }

        return BasePage.copyPageInfo(departmentPage, treeResponses);
    }

    /**
     * 获取科室详情
     * @param id Integer 科室id
     * @return BaseResult<OrganDepartment> 科室详情
     */
    @Override
    public OrganDepartmentTreeResponse getInfoById(Integer id) {
        OrganDepartment department = getById(id);
        if(Objects.isNull(department)){
            return null;
        }
        return OrganDepartmentTreeResponse.transform(department);
    }


    /**
     * 根据已有的父节点响应信息，递归构建科室树
     *
     * @param responses 当前层级的响应对象列表（包含父节点信息）
     * @param parentIds 父节点ID列表
     */
    private void findTree(List<OrganDepartmentTreeResponse> responses, List<Integer> parentIds) {
        if (CollUtil.isEmpty(parentIds)) {
            return;
        }

        // 一次性查询所有子节点
        List<OrganDepartment> departments = lambdaQuery()
                .in(OrganDepartment::getParentId, parentIds)
                .list();

        if (CollUtil.isEmpty(departments)) {
            return;
        }

        // 按 parentId 分组
        Map<Integer, List<OrganDepartment>> departmentMap = departments.stream()
                .collect(Collectors.groupingBy(OrganDepartment::getParentId));

        for (Integer parentId : parentIds) {
            /*OrganDepartment self = getById(parentId);
            if (self == null || self.getIsNexFalg() != 1) {
                // 如果当前节点不存在或没有子节点，设置空列表
                responses.forEach(r -> {
                    if (r.getId().equals(parentId)) {
                        r.setChild(Collections.emptyList());
                    }
                });
                continue;
            }*/

            List<OrganDepartment> children = departmentMap.get(parentId);
            if (CollUtil.isEmpty(children)) {
                responses.forEach(r -> {
                    if (r.getId().equals(parentId)) {
                        r.setChild(Collections.emptyList());
                    }
                });
                continue;
            }

            // 转换子节点为响应对象
            List<OrganDepartmentTreeResponse> childResponses = children.stream()
                    .map(OrganDepartmentTreeResponse::transform)
                    .collect(Collectors.toList());

            // 设置到父节点的 child 字段中
            responses.forEach(r -> {
                if (r.getId().equals(parentId)) {
                    r.setChild(childResponses);
                }
            });

            // 递归处理子节点
            List<Integer> childIds = childResponses.stream()
                    .map(OrganDepartmentTreeResponse::getId)
                    .collect(Collectors.toList());

            findTree(childResponses, childIds);
        }
    }


}
